import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';
import { LDrawLoader } from 'three/addons/loaders/LDrawLoader.js';
export default class ZThree {
    constructor(id) {
        this.id = id
        this.el = document.getElementById(id)
    }
    initThree() {
        let width = this.el.offsetWidth;
        let height = this.el.offsetHeight;
        this.scene = new THREE.Scene();
        this.camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
        this.renderer = new THREE.WebGLRenderer({
            antialias: true//反锯齿
        });
        this.renderer.setSize(this.el.offsetWidth, this.el.offsetHeight);
        this.el.appendChild(this.renderer.domElement);
        window.addEventListener("resize", () => {
            // 更新摄像头
            this.camera.aspect = this.el.offsetWidth / this.el.offsetHeight;
            //   更新摄像机的投影矩阵
            this.camera.updateProjectionMatrix();
            //   更新渲染器
            this.renderer.setSize(this.el.offsetWidth, this.el.offsetHeight);
            //   设置渲染器的像素比
            this.renderer.setPixelRatio(window.devicePixelRatio);
            // geometry.center();
        });
    }
    initOrbitControls() {
        const controls = new OrbitControls(this.camera, this.renderer.domElement);
        this.controls = controls;
    }
    initAxesHelper() {
        const axesHelper = new THREE.AxesHelper(5);
        this.scene.add(axesHelper);
    }
    initLight() {
        const ambientLight = new THREE.AmbientLight(0xffffff, 5);
        this.scene.add(ambientLight);
        const dirLight = new THREE.DirectionalLight(0xffffff, 5);
        this.scene.add(dirLight);
        dirLight.shadow.mapSize.width = 1024; // default
        dirLight.shadow.mapSize.height = 1024; // default
        dirLight.shadow.camera.near = 0.1; // default
        dirLight.shadow.camera.far = 100; // default
        dirLight.shadow.camera.left = 100; // default
        dirLight.shadow.camera.right = -100; // default
        dirLight.shadow.camera.top = 100; // default
        dirLight.shadow.camera.bottom = -100; // default
        const camerahelper = new THREE.CameraHelper(dirLight.shadow.camera);
        this.scene.add(camerahelper);
    }
    //加载模型
    loaderModel(option) {//option= type url onLoad  onProgress onError
        switch (option.type) {
            case 'obj':
                if (!this.objloader) {
                    this.objloader = new OBJLoader();
                    this.objloader.load(option.url, option.onLoad, option.onProgress, option.onError)
                }
                break;
            case 'gltf':
            case 'glb':
                if (!this.gltfloader) {
                    this.gltfloader = new GLTFLoader();
                    const dracoLoader = new DRACOLoader();
                    dracoLoader.setDecoderPath('draco/gltf/');
                    this.gltfloader.setDRACOLoader(dracoLoader);
                }
                this.gltfloader.load(option.url, option.onLoad, option.onProgress, option.onError)
                break;
            case 'mpd':
                if (!this.mpdloader) {
                    this.mpdloader = new LDrawLoader();
                    this.mpdloader.load(option.url, option.onLoad, option.onProgress, option.onError)
                }
                break;
            case 'rgbe':
                if (!this.rgbeloader) {
                    this.rgbeloader = new RGBELoader();
                    this.rgbeloader.load(option.url, option.onLoad, option.onProgress, option.onError)
                }
                break;
            default:
                console.log('不存在obj、gltf、glb、pmd、rgbe等格式');
                break
        }
    }
    interatorLoader(objFileList, onProgress, onAllLoad) {//各种模型中的多个模型
        var currentIndex = 0;
        var that = this;
        function interateLoadForInt() {
            that.loaderModel({
                type: objFileList[currentIndex].type,
                url: objFileList[currentIndex].url,
                onLoad: function (object) {
                    if (typeof objFileList[currentIndex].onLoad == 'function') {
                        objFileList[currentIndex].onLoad(object)
                        currentIndex++
                        if (currentIndex < objFileList.length) {
                            interateLoadForInt()
                        } else {
                            onAllLoad()
                        }
                    }
                },
                onProgress: function (xhr) {
                    onProgress()
                },
                onError: function (err) {
                    console.log('加载错误!');
                }
            })
        }
        interateLoadForInt()
    }
    initRaycaster(callback, model = this.scene.children, eventName = 'click') {
        this.raycaster = new THREE.Raycaster();
        const pointer = new THREE.Vector2();
        this.el.addEventListener(eventName, (event) => {
            pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
            pointer.y = - (event.clientY / window.innerHeight) * 2 + 1;
            let activeObj = this.initSelect(pointer, model)
            if (callback) {
                callback(activeObj)
            }
        })
    }
    initSelect(pointer, model) {
        this.raycaster.setFromCamera(pointer, this.camera);
        // 计算物体和射线的焦点
        const intersects = this.raycaster.intersectObjects(model)
        console.log('intersects', intersects[0]);

        if (intersects.length > 0) {
            return intersects[0]
        } else {
            return;
        }
    }
    initSky() {
        const loader = new THREE.CubeTextureLoader();
        loader.setPath('textures/sky_day/');
        const textureCube = loader.load(['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg']);
        //左        右           上           下         前           后
        this.scene.background = textureCube;
    }
    animate(callback) {
        requestAnimationFrame(() => this.animate(callback));
        callback()
    }
}